package com.myway.service.ibe.command;

import com.travelsky.ibe.client.pnr.*;

import java.util.*;

/**
 * Created by yufei on 2018/6/28.
 * 改期升舱，需要换开票面
 */
public class ChangeTicketPNRCommand extends BaseIBECommand{
    //升舱：换开票面的改升操作，生产上采用占位PNR的方式实现升舱，且大多原票面信息可以从数据库中提取
    //方法：updatePnr，传入的参数为要改升的PNR，新添加信息bookinformation，删除所有index[]。
    //说明：这里以成人、儿童、带婴儿、往返航段、修改第一个航段为F舱为例，采用部分参数写死的方式，可以学习PNR信息提取相关API的用法。
    //注意事项：a、index[]中存放的该条记录在PNR中的行号
    //b、改升的时候不要把第一航段的出发日期改到第二航段之前
    //c、索引从0开始，行号从1开始。
    //d、OI项票联号，往返客票为1200
    //e、TKNE项要删除干净，因为要生成新票面，原TKNE中的票号已不能使用
    //f、出过票的PNR才能改升
    public void change(String pnr) throws Exception{
        PnrManage pm=new PnrManage();
        RT rt = new RT();
        // 第一步、连接主机
        this.configIBEClient(pm);
        this.configIBEClient(rt);
        //第二步、提取PNR
        RTResult rtResult =rt.retrieve(pnr);
        //第三步、创建要删除的信息pnr序号集合
        List indextemp = new ArrayList();
        //第四步、 创建要更新的信息组
        BookInfomation bookInfomation = new BookInfomation();
        //这里以成人、儿童、带婴儿、往返航段、修改第一个航段为F舱为例
        //第五步、添加新的航段组。
        PNRAirSeg oldPNRAirSeg=rtResult.getAirSegAt(0);//航段索引从0开始
        BookAirSeg newBookAirSeg = new BookAirSeg();
        newBookAirSeg.setActionCode("NN");
        newBookAirSeg.setAirNo(oldPNRAirSeg.getAirNo());
        newBookAirSeg.setDepartureTime(oldPNRAirSeg.getDepartureTime());//可以改期
        newBookAirSeg.setOrgCity(oldPNRAirSeg.getOrgCity());
        newBookAirSeg.setDesCity(oldPNRAirSeg.getDesCity());
        newBookAirSeg.setFltClass('F');
        newBookAirSeg.setTktNum(oldPNRAirSeg.getTktNum());
        bookInfomation.addAirSeg(newBookAirSeg);
        indextemp.add(oldPNRAirSeg.getIndex());//添加该pnr序号以待删除
        /*
         *第六步、添加OI项
         */
        //首先获取原PNR票号
        Map infTktNo = new HashMap();// 婴儿原票号
        Map tktNo = new HashMap();// 成人和儿童原票号
        for (int i = 0; i < rtResult.getTktnosCount(); i++) {
            PNRTktNo pnrTktNo =rtResult.getTktnoAt(i) ;
            if (null != pnrTktNo&&"".equals(pnrTktNo.getRemark())) {//成人和儿童的remark为空字符串
                tktNo.put(pnrTktNo.getPsgrID(), pnrTktNo.getTktNo());
            }
            if (null != pnrTktNo&&"IN".equals(pnrTktNo.getRemark())){//婴儿的remark为IN
                infTktNo.put(pnrTktNo.getPsgrID(), pnrTktNo.getTktNo());
            }
        }
        //添加OI项
        Set psgrids = tktNo.keySet();
        Set infPsgrids = infTktNo.keySet();
        String psgrid = "";
        String ticketNo = "";
        //成人和儿童OI
        for (Iterator iterator = psgrids.iterator(); iterator.hasNext();) {
            psgrid = (String) iterator.next();
            ticketNo = (String)tktNo.get(psgrid);
            BookOI oi = new BookOI();
            oi.setCoupon("1200");//单航段客票为1000，指同一张票面上的航段都需要OI
            oi.setPsgrid(psgrid);
            oi.setTktno(ticketNo);
            bookInfomation.addOI(oi);
        }
        //婴儿OI
        for (Iterator iterator = infPsgrids.iterator(); iterator.hasNext();) {
            psgrid = (String) iterator.next();
            ticketNo = (String)infTktNo.get(psgrid);
            BookOI oi = new BookOI();
            oi.setCoupon("1200");
            oi.setPsgrid(psgrid);
            oi.setTktno(ticketNo);
            oi.setInfant(true);//区别
            bookInfomation.addOI(oi);
        }
        /*
         *第七步、添加FC、FN
         */
        /*
         * 因为出过票，FC项已丢失，航段价无法获取，所以采用把新票面总价加到最后一个航段的方式创建FC
         * 对于包含成人、儿童、婴儿的PNR，FC项不同，所以在添加FC项时需添加旅客标识
         */
        /*
         * 确认旅客信息类型
         */
        int adultCnt = 0;// 成人旅客计数
        int infantCnt = 0;// 婴儿旅客计数
        int childCnt = 0;// 儿童旅客计数
        List childNames = new ArrayList();// 儿童姓名集合
        List adultNames = new ArrayList();// 成人姓名集合
        Vector psgrs = rtResult.getPassengers();
        //BookPassenger psgr = new BookPassenger("成人甲");
        //BookPassenger psgr2 = new BookPassenger("成人乙");
//      for (int i = 0; i < psgrs.size(); i++) {
//          if (PNRPassenger.ADULT == (psgrs.get(i)).getPassengerType()) {// 判断是否含有成人旅客，确认成人旅客数量
//              adultCnt++;
//              adultNames.add(((BookInfant) psgrs.get(i)).getName());
//          }
//          if (3 == (psgrs.get(i)).getPassengerType()) {// 判断是否含有儿童旅客，确认儿童旅客数量，因为PNRPassenger.CHILD在API和实际值不同，所以采用数值
//              childCnt++;
//              childNames.add(psgrs.get(i).getName());
//          }
//      }
        infantCnt = rtResult.getInfantsCount();// 判断是否含有婴儿旅客，确认婴儿数量
        //成人FC、FN、FP
        if(0!=adultCnt){
            BookFC adultFc = new BookFC();
            adultFc.addFC(rtResult.getAirSegAt(0).getOrgCity(),rtResult.getAirSegAt(0).getDesCity(),
                    "SC","F",-1, -1, -1, null, null, false, true,
                    null, -1, null, -1, null, null, null);//第四个参数为-1表示此处不填写价格
            adultFc.addFC(rtResult.getAirSegAt(1).getOrgCity(),rtResult.getAirSegAt(1).getDesCity(),
                    "SC",String.valueOf(rtResult.getAirSegAt(1).getFltClass()),1200.00, -1, -1, null, null, false, true,
                    null, -1, null, -1, null, null, null);//在最后一个航段填写价格1200.00
            for (int k = 0; k < adultNames.size(); k++) {//添加旅客标识
                adultFc.addPsgrname(adultNames.get(k).toString());
            }
            bookInfomation.addFC(adultFc);
            BookFN adultFn = new BookFN();// 成人 FN
            adultFn.setAmount(BookFN.R, "CNY", 1200.00);//新票面价
            adultFn.setAmount(BookFN.S, "CNY", 200.00);//票面差价
            adultFn.setAmount(BookFN.A, "CNY", 200.00);//总差价
            adultFn.setC(0);
            adultFn.addTax(BookFN.T, "CNY", 100.00, "CN");
            adultFn.addTax(BookFN.T, "CNY", 140.00, "YQ");
            for (int k = 0; k < adultNames.size(); k++) {
                adultFn.addPsgrname(adultNames.get(k).toString());
            }
            bookInfomation.addFN(adultFn);
            BookFP fp = new BookFP();// FP不可省掉
            fp.setFp("cc/23");
            bookInfomation.addFP(fp);
        }
        //儿童FC、FN，票价不同
        if(0!=childCnt){
            BookFC childFc = new BookFC();
            childFc.addFC(rtResult.getAirSegAt(0).getOrgCity(),rtResult.getAirSegAt(0).getDesCity(),
                    "SC","F",-1, -1, -1, null, null, false, true,
                    null, -1, null, -1, null, null, null);//第四个参数为-1表示此处不填写价格
            childFc.addFC(rtResult.getAirSegAt(1).getOrgCity(),rtResult.getAirSegAt(1).getDesCity(),
                    "SC",String.valueOf(rtResult.getAirSegAt(1).getFltClass()),600.00, -1, -1, null, null, false, true,
                    null, -1, null, -1, null, null, null);//在最后一个航段填写价格
            for (int k = 0; k < childNames.size(); k++) {//添加旅客标识
                childFc.addPsgrname(childNames.get(k).toString());
            }
            bookInfomation.addFC(childFc);
            BookFN childFn = new BookFN();// 儿童FN
            childFn.setAmount(BookFN.R, "CNY", 600.00);//RCNY
            childFn.setAmount(BookFN.S, "CNY", 100.00);//SCNY
            childFn.setAmount(BookFN.A, "CNY", 100.00);//ACNY
            childFn.setC(0);
            childFn.addTax(BookFN.T, "CNY", 140.00, "YQ");
            childFn.addTax(BookFN.T, "CNY", BookFN.EXEMPTTAX, "CN");
            for (int k = 0; k < childNames.size(); k++) {
                childFn.addPsgrname(childNames.get(k).toString());
            }
            bookInfomation.addFN(childFn);
            if (0 == adultCnt) {//如果没有成人才追加FP
                BookFP fp = new BookFP();// FP
                fp.setFp("cc/23");
                bookInfomation.addFP(fp);
            }
        }
        //婴儿FC、FN、FP，票价不同，特殊标识infant
        if (0 != infantCnt) {
            BookFC infantFc = new BookFC();
            infantFc.addFC(rtResult.getAirSegAt(0).getOrgCity(), rtResult.getAirSegAt(0).getDesCity(), "SC", "F", -1, -1, -1, null,
                    null, false, true, null, -1, null, -1, null, null, null);// 第四个参数为-1表示此处不填写价格
            infantFc.addFC(rtResult.getAirSegAt(1).getOrgCity(), rtResult.getAirSegAt(1).getDesCity(), "SC", String.valueOf(rtResult
                            .getAirSegAt(1).getFltClass()), 120.00, -1, -1, null, null,
                    false, true, null, -1, null, -1, null, null, null);// 在最后一个航段填写价格
            // 婴儿有特殊的标识项，所以可以不添加旅客标识
            infantFc.setInfant(true);
            bookInfomation.addFC(infantFc);
            BookFN infantFn = new BookFN();// 婴儿FN
            infantFn.setAmount(BookFN.F, "CNY", 60.00);
            infantFn.setAmount(BookFN.S, "CNY", 60.00);
            infantFn.setAmount(BookFN.A, "CNY", 60.00);
            infantFn.setC(0);
            infantFn.addTax(BookFN.T, "CNY", BookFN.EXEMPTTAX, "YQ");
            infantFn.addTax(BookFN.T, "CNY", BookFN.EXEMPTTAX, "CN");
            infantFn.setInfant(true);//区别标识
            bookInfomation.addFN(infantFn);
            BookFP fp = new BookFP();// FP
            fp.setFp("cc/23");
            fp.setInfant(true);// 区别
            bookInfomation.addFP(fp);
        }
        bookInfomation.setTimelimit("2012-10-23 12:00:00");// TK:TL
        /*
         *第八步、获取要删除T、FN、TN、FP、剩下要修改航段的TKNE的PNR序号
         */
        if (0 != rtResult.getTktsCount()) {// 出票组T
            for (int i = 0; i < rtResult.getTktsCount(); i++) {
                if (null != rtResult.getTktAt(i)) {
                    indextemp.add(rtResult.getTktAt(i).getIndex());
                }
            }
        }
        if (0 != rtResult.getFNsCount()) {// FN
            for (int i = 0; i < rtResult.getFNsCount(); i++) {
                if (null != rtResult.getFNAt(i)) {
                    indextemp.add(rtResult.getFNAt(i).getIndex());
                }
            }
        }
        if (0 != rtResult.getTktnosCount()) {// TN
            for (int i = 0; i < rtResult.getTktnosCount(); i++) {
                if (null != rtResult.getTktnoAt(i)) {
                    indextemp.add(rtResult.getTktnoAt(i).getIndex());
                }
            }
        }
        if (null != rtResult.getFps() && 0 != rtResult.getFps().size()) {// FP
            for (int i = 0; i < rtResult.getFps().size(); i++) {
                if (null != rtResult.getFpAt(i)) {
                    indextemp.add(rtResult.getFpAt(i).getIndex());
                }
            }
        }
        if (null != rtResult.getSsrs() && 0 != rtResult.getSSRsCount()) {// TKNE
            for (int i = 0; i < rtResult.getSSRsCount(); i++) {
                if (null != rtResult.getSSRAt(i)) {
                    if ("TKNE".equals(rtResult.getSSRAt(i).getSSRType())) {
                        indextemp.add(rtResult.getSSRAt(i).getIndex());
                    }
                }
            }
        }
        Integer[] indexsTemp=(Integer[])indextemp.toArray(new Integer[0]);
        int[]index=new int[indexsTemp.length];
        for(int i=0;i<indexsTemp.length;i++){
            index[i]=indexsTemp[i].intValue();
        }
        //第九步、升舱
        String status=pm.updatePnr(pnr, bookInfomation, index);
        //第十步、打印出票
        if("OK".equals(status)){
            etdz(pnr);
        }
    }

    /**
     * 出票
     * @param pnr  PNR编号
     * @throws Exception
     */
    public void etdz(String pnr){
        ETDZ etdz = new ETDZ();
        this.configIBEClient(etdz);
        //issueTicket(java.lang.String pnrno,int printerNo)pnrno(PNR编号),printerNo（打票机编号）
        try {
            System.out.println(etdz.issueTicket(pnr, 2));//返回OK
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
